import * as T from '../actionTypes/tab'
import { AuthoritySchema } from '@src/components/schema/authority'
import { WindowSchema } from '@src/components/schema/window'
import { MenuSchema } from '../../components/schema/menu';

export interface INIT_TAB_STATE {
  menus: AuthoritySchema[]
  windows: WindowSchema[]
  activeWindowId: string
}

const initialState: INIT_TAB_STATE = {
  menus: [], // 菜单列表
  windows: [], // 当前已打开的窗口列表
  activeWindowId: '' // 当前查看的窗口id
}

// 设置tab页面信息
function reducer (state = initialState, action: { type: string, data: any }) {
  switch (action.type) {
    case T.ADD_WINDOW: // 打开新窗口
      return addWindow(state, action.data)
    case T.DEL_WINDOW: // 关闭指定窗口
      return delWindow(state, action.data)
    case T.MODIFY_WINDOW_META: // 修改窗口元数据
      return modifyWindowMeta(state, action.data)
    case T.SET_ACTIVE_WINDOW_ID: // 设置当前操作窗口
      return setActiveWindowId(state, action.data)
    case T.INIT_MENU_LIST: // 初始化菜单
      return initMenuList(state, action.data)
    case T.MODIFY_WINDOW_ID: // 修改窗口id
      return modifyWindowId(state, action.data)
    case T.CLEARWINDOW: // 清空窗口
      return clearWindow(state, action.data)
    default:
      return state
  }
}

// 打开新窗口
function addWindow (state: INIT_TAB_STATE, { id = '', title = '无标题', componentName = '', closable = true, meta = {}, width = 0, isHome = false, forceRefresh = false }) {
  const newState: INIT_TAB_STATE = {} as INIT_TAB_STATE
  const index = getIndexById(state.windows, id)
  const windowObj: WindowSchema = { id, title, componentName, closable, meta, width, isHome }
  if (index !== -1) {
    newState.windows = state.windows.slice()
    const currentWindow = newState.windows[index]
    currentWindow.meta = meta
    newState.activeWindowId = currentWindow.id
    if (currentWindow.componentName !== componentName) {
      currentWindow.componentName = componentName
    }
    if (currentWindow.title !== title && title !== '无标题') {
      currentWindow.title = title
    }
    if (forceRefresh) {
      newState.windows.splice(index, 1, { ...currentWindow, key: currentWindow.id + Date.now() })
    } else {
      newState.windows = state.windows.slice()
    }
    return {
      ...state,
      ...newState
    }
  }
  windowObj.width = getTitleWidth(windowObj.title)
  windowObj.key = id + Date.now()
  if (isHome) {
    windowObj.width += 20
  }
  newState.windows = state.windows.slice()
  newState.windows.push(windowObj)
  newState.activeWindowId = windowObj.id
  setTimeout(() => {
    document.documentElement.scrollTop = 0
  }, 200)
  return {
    ...state,
    ...newState
  }
}

// 关闭指定窗口
function delWindow (state: INIT_TAB_STATE, id: string) {
  let { activeWindowId } = state
  const windows = state.windows.slice()
  const index = getIndexById(windows, id)
  if (index !== -1) {
    if (activeWindowId === windows[index].id && windows.length > 1) {
      if (index === 0) {
        activeWindowId = windows[1].id
      } else {
        activeWindowId = windows[index - 1].id
      }
    }
    windows.splice(index, 1)
  } else {
    console.warn('要关闭的窗口不存在！')
  }
  if (windows.length === 0) {
    activeWindowId = ''
  }
  document.documentElement.scrollTop = 0
  return {
    ...state,
    windows,
    activeWindowId
  }
}

// 修改窗口元数据
function modifyWindowMeta (state: INIT_TAB_STATE, { id, ...args }: { id: string }) {
  const windows = state.windows.slice()
  const index = getIndexById(windows, id)
  if (index !== -1) {
    windows[index] = { ...windows[index], ...args }
  } else {
    console.warn('要修改元数据的窗口不存在！')
  }
  return {
    ...state,
    windows
  }
}

// 修改窗口的id
function modifyWindowId (state: INIT_TAB_STATE, { id, newId }: { id: string, newId: string }) {
  let activeWindowId = state.activeWindowId
  const windows = state.windows.slice()
  const index = getIndexById(windows, id)
  if (index !== -1) {
    const page = { ...windows[index], id: newId }
    windows.splice(index, 1, page)
  } else {
    console.warn('要修改id的窗口不存在！')
  }
  if (activeWindowId === id) {
    activeWindowId = newId
  }
  return {
    ...state,
    activeWindowId,
    windows
  }
}

// 设置当前操作窗口
function setActiveWindowId (state: INIT_TAB_STATE, id: string) {
  document.documentElement.scrollTop = 0
  return {
    ...state,
    activeWindowId: id
  }
}

// 初始化菜单
function initMenuList (state: INIT_TAB_STATE, menus: MenuSchema[] = []) {
  menus.forEach(menu => {
    menu.showChildren = true
  })
  return {
    ...state,
    menus
  }
}

// 关闭窗口
function clearWindow (state: INIT_TAB_STATE, noCloseAll: boolean = true) {
  let windows: WindowSchema[] = []
  let activeWindowId = ''
  if (noCloseAll) {
    windows = state.windows.filter(li => !li.closable)
    activeWindowId = windows[0].id
  }
  if (state.windows.length === 1 && windows.length === 1 && state.windows[0].id === windows[0].id) {
    return state
  }
  document.documentElement.scrollTop = 0
  return {
    ...state,
    windows,
    activeWindowId
  }
}

/**
 * 获取相同id项在数组的下标
 * @param {*} list 数组
 * @param {*} id 唯一标识
 */
function getIndexById (list: WindowSchema[], id: string) {
  let index = -1
  for (let i = 0; i < list.length; i++) {
    if (list[i].id === id) {
      index = i
      break
    }
  }
  return index
}

/**
 * 获取标题所战像素长度
 * @param {*} title 标题
 */
function getTitleWidth (title = ''): number {
  const box = document.createElement('div')
  box.style.display = 'inline-block'
  box.style.position = 'fixed'
  box.style.top = '-100px'
  box.style.left = '0'
  box.innerHTML = title
  document.body.appendChild(box)
  const width = box.offsetWidth
  document.body.removeChild(box)
  return width
}

export default reducer
